
import { IElementView } from "./IElementView.js";

export class IElementEvent extends IElementView {
    constructor() {
        super();
        this.m_modal = false; // 模态元素
        this.m_event_listeners = {}; // 事件集 { event_name: [event_listener, ...], ... }
    }

    SetModal(modal) { this.m_modal = modal; }
    IsModal() { return this.m_modal; }
    
    AddEventListener(event_name, event_listener, capture) {
        event_name = event_name + (capture ? "_capture" : "_bubble");
        this.m_event_listeners[event_name] = this.m_event_listeners[event_name] || [];
        this.m_event_listeners[event_name].push(event_listener);
    }

    RemoveEventListener(event_name, event_listener, capture) {
        event_name = event_name + (capture ? "_capture" : "_bubble");
        this.m_event_listeners[event_name] = this.m_event_listeners[event_name] || [];
        const index = this.m_event_listeners[event_name].indexOf(event_listener);
        if (index >= 0) {
            this.m_event_listeners[event_name].splice(index, 1);
        }
    }

    DispatchEvent(event, capture) {
        const event_name = event.GetName() + (capture ? "_capture" : "_bubble");
        const event_listeners = this.m_event_listeners[event_name] || [];
        for (let i = 0; i < event_listeners.length; i++) {
            const event_listener = event_listeners[i];
            if (typeof event_listener === "function") {
                event_listener(event);
            } else {
                if (typeof event_listener === "object" && typeof event_listener.handleEvent === "function") {
                    event_listener.handleEvent(event);
                }
            }
        }
    }

    GetElementByXY(x, y, e) {
        const viewport_x = this.GetViewPortX();
        const viewport_y = this.GetViewPortY();
        const viewport_width = this.GetViewPortWidth();
        const viewport_height = this.GetViewPortHeight();
        // 先检测定位子元素
        const descendants = this.GetPositionDescendants();
        for (let i = descendants.length - 1; i >= 0; i--) {
            const descendant = descendants[i];
            if (!descendant.IsVisible() || descendant.IsDragging()) {
                continue;
            }
            const element = descendant.GetElementByXY(x, y, e);
            if (element) {
                if (x >= viewport_x && x < (viewport_x + viewport_width) && y >= viewport_y && y < (viewport_y + viewport_height)) {
                    e.PushEventElement(this);
                }
                return element;
            }
        }

        if (x < viewport_x || x >= (viewport_x + viewport_width) || y < viewport_y || y >= (viewport_y + viewport_height)) {
            if (this.IsModal()) {
                e.PushEventElement(this);
                return this;
            } else {
                return null;
            }
        }

        e.PushEventElement(this);
        // 事件顺序应与渲染顺序相反，后渲染的元素优先响应事件
        const childrens = this.GetChildrens();
        for (let i = childrens.length - 1; i >= 0; i--) {
            const children = childrens[i];
            if (!children.IsVisible() || children.IsDragging() || children.GetPositionAncestor()) {
                continue;
            }
            const element = children.GetElementByXY(x, y, e);
            if (element) return element;
        }
        return this;
    }

    CaptureMouse() {
        this.GetWindow().SetMouseCaptureElement(this);
    }

    ReleaseMouse() {
        if (this.GetWindow().GetMouseCaptureElement() === this) {
            this.GetWindow().SetMouseCaptureElement(null);
        }
    }

    OnMouseDown(e) { }
    OnMouseMove(e) { }
    OnMouseUp(e) { }
    OnClick(e) { }
    OnContextMenu(e) { }
    OnMouseEnter() {
        // console.log("Mouse Enter", this.GetTagName());
    }
    OnMouseLeave() {
        // console.log("Mouse Leave", this.GetTagName());
    }
}